<template>
  <div class="app-container">
    <el-row :gutter="10">
      <el-col :md="6">
        <el-col :md="20">
          <el-input v-model="filterAreaText" size="small" clearable align="center" class="filter-item " style="position: relative;top: -1px;margin-bottom: 15px" placeholder="输入字段值" />
        </el-col>
        <el-tree
          v-loading="loading"
          ref="areaTree"
          :data="data"
          :current-node-key="currentNodekey"
          :default-expanded-keys="expandedkeys"
          :filter-node-method="filterNode"
          :expand-on-click-node="true"
          :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
          :select-on-indeterminate="true"
          row-key="id"
          border
          highlight-current-row
          size="small"
          class="filter-tree el-tree"
          highlight-current
          @node-contextmenu="rightClick"
          @node-click="handleNodeClick"
        />
        <div v-if="tmDisplay" id="perTreeMenu" :style="{...rightMenu}" class="tree_menu">
          <ul>
            <li @click="$refs.addForm.dialog = true;addDict()">
              <i class="el-icon-circle-plus-outline"></i>
              添加子分类
            </li>
            <li @click="$refs.editForm.dialog = true;editDict()">
              <i class="el-icon-edit"></i>
              编辑子分类
            </li>
            <li @click="delDict">
              <i class="el-icon-remove-outline"></i>
              删除子分类
            </li>
          </ul>
        </div>
        <addForm ref="addForm" :right-click-dict="rightClickDict" :current-data="currentData" :dict-id="currentId" :is-add="true" @init="init"/>
        <editForm ref="editForm" :right-click-dict="rightClickDict" :current-data="currentData" :dict-id="currentId" :is-add="false" @init="init"/>
      </el-col>
      <el-col :md="18">
        <eHeader :current-data="currentData" :is-add="true" :dict-id="currentId" :query="query" @getDictDetail="getDictDetail"/>
        <!--表格渲染-->
        <el-table
          v-loading="dictLoading"
          ref="treeTable"
          :data="dictTree"
          :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
          :select-on-indeterminate="true"
          :load="load"
          row-key="id"
          size="small"
          border
          lazy
          highlight-current-row
          height="780"
          style="width: 100%;margin-bottom: 20px;"
          @select-all="selectAll"
          @selection-change="handleSelectionChange">
          <el-table-column
            fixed
            align="center"
            type="selection"
            width="40">
          </el-table-column>
          <el-table-column align="center" type="index" width="50" />
          <el-table-column prop="label" label="字典名称" width="280">
          </el-table-column>
          <el-table-column prop="dict_code" label="字典编码" align="center" width="260px">
          </el-table-column>
          <el-table-column prop="dict_val" label="字典值" align="center" width="200px">
          </el-table-column>
          <el-table-column prop="is_enabled" label="是否有效" align="center" width="100px">
            <template
              slot-scope="scope"
            >{{ scope.row.is_enabled ? '是': '否' }}
            </template>
          </el-table-column>
          <el-table-column prop="create_user" label="创建人" align="center" width="120px">
          </el-table-column>
          <el-table-column prop="create_date" label="创建时间" align="center" width="160px">
          </el-table-column>
          <el-table-column prop="update_user" label="修改人" align="center" width="120px">
          </el-table-column>
          <el-table-column prop="update_date" label="修改时间" align="center" width="160px">
          </el-table-column>
          <el-table-column label="操作" width="150px" fixed="right" align="center">
            <template slot-scope="scope">
              <edit v-if="checkPermission(['admin','dict_all','dict_edit'])" :current-data="currentData" :dict-id="currentId" :is-add="false" :data="scope.row" :sup_this="sup_this" @getDictDetail="getDictDetail"/>
              <el-popover
                v-if="checkPermission(['admin','dict_all','dict_delete'])"
                :ref="scope.row.id"
                placement="top"
                width="200">
                <p>确定删除吗,如果存在下级节点则节点上升，此操作不能撤销！</p>
                <div style="text-align: right; margin: 0">
                  <el-button size="mini" type="text" @click="$refs[scope.row.id].doClose()">取消</el-button>
                  <el-button :loading="delLoading" type="primary" size="mini" @click="subDelete(scope.row.id)">确定</el-button>
                </div>
                <el-button slot="reference" type="danger" icon="el-icon-delete" size="mini"></el-button>
              </el-popover>
            </template>
          </el-table-column>
        </el-table>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import checkPermission from '@/utils/permission'
import { del, multiDelete, getDictDetail, getDictList } from '@/api/dictDetail'
import { multiDeleteDict } from '@/api/dict'
import treeTable from '@/components/TreeTable'
import initData from '@/mixins/initData'
import { parseTime } from '@/utils/index'
import eHeader from './module/header'
import edit from './module/edit'
import addForm from './module/form/dict'
import editForm from './module/form/dict'
import { Notification } from 'element-ui'

export default {
  name: 'Dict',
  components: { eHeader, edit, treeTable, addForm, editForm },
  mixins: [initData],
  data() {
    return {
      tmDisplay: false,
      rightMenu: {},
      rightClickDict: {},
      contextMenuTarget: null,
      contextMenuVisible: false,
      dictLoading: false,
      dictTree: [],
      formDictTree: [],
      currentData: {},
      currentId: '',
      filterAreaText: '',
      currentNodekey: '', // 默认选中的节点树
      expandedkeys: [], // 默认展开的节点树
      delLoading: false, sup_this: this, dicts: [],
      props: {
        label: 'label',
        children: 'children',
        isLeaf: 'leaf'
      }
    }
  },
  watch: {
    filterAreaText(val) {
      this.$refs.areaTree.filter(val)
      // vue-context-menu 需要传入一个触发右键事件的元素，等页面 dom 渲染完毕后才可获取
      this.contextMenuTarget = document.querySelector('#el-tree')
      // 获取所有的 treeitem，循环监听右键事件
      const tree = document.querySelector('#el-tree [role="treeitem"]')
      tree.forEach(i => {
        i.addEventListener('contextmenu', event => {
          // 如果右键了，则模拟点击这个treeitem
          event.target.click()
        })
      })
    },
    data(val) {
      const temp = JSON.parse(JSON.stringify(val[0]))
      delete temp.children
      this.currentData = temp
    }
  },
  created() {
    this.$nextTick(() => {
      this.init(
        this.size = 10
      )
    })
  },
  methods: {
    parseTime,
    checkPermission,
    beforeInit() {
      this.url = 'api/dict/'
      const sort = 'id'
      this.params = { ordering: sort }
      return true
    },
    rightClick(e, data, node, comp) {
      console.log('data', data)
      this.rightClickDict = data
      this.rightMenu = { top: e.pageY + 'px', left: e.pageX + 'px' }
      this.tmDisplay = true
      const self = this
      document.onclick = function(ev) {
        if (ev.target !== document.getElementById('perTreeMenu')) {
          self.tmDisplay = false
        }
      }
    },
    addDict() {
      this.$refs.addForm.getDictTree()
    },
    editDict() {
      this.$refs.editForm.getDictTree()
    },
    delDict() {
      this.$confirm('确定移除吗？').then(() => {
        if (this.rightClickDict) {
          this.loading = true
          var result = []
          try {
            result = this.traverse(this.rightClickDict)
          } catch (error) {
            this.loading = false
            console.error(error)
          }
          console.log('result', result)
          console.log('result', result.toString())
          if (result.length > 0) {
            multiDeleteDict(result.toString()).then(res => {
              this.loading = false
              this.init()
              this.$message({
                showClose: true,
                type: 'success',
                message: '删除成功!',
                duration: 2500
              })
            }).catch(err => {
              this.loading = false
              Notification.error({
                title: '错误',
                message: '删除失败'
              })
              console.log(err)
            })
          } else {
            this.loading = false
          }
        }
      }).catch(() => {
      })
    },
    load(tree, treeNode, resolve) {
      const query = this.query
      const value = query.value
      const dictParams = { parent_code: tree.dict_code }
      if (value) { dictParams['label'] = value }
      getDictList(dictParams).then(res => {
        if (res.code === 200) {
          resolve(res.data.list)
        }
        this.dictLoading = false
      }).catch(err => {
        this.dictLoading = false
        console.log(err)
      })
    },
    // 遍历子树，删除
    traverse(node) {
      var result = []
      result.push(node.id)
      if (node.children) {
        node.children.forEach(i => {
          result.push(i.id)
          // 有⼦数据的先遍历⼦数据
          i.children && this.traverse(i.children)
        })
      }

      return result
    },
    // 选择地区
    handleNodeClick(data) {
      this.tmDisplay = false
      this.currentData = data
      this.currentId = data.dict_id
      if (data.dict_code === 'RegisterArea' ||
      data.dict_code === 'Technosphere1' ||
      data.dict_code === 'DocDataBank') {
        this.getDictList()
      } else {
        this.getDictDetail()
      }
    },
    getDictDetail() {
      this.dictLoading = true
      const query = this.query
      const value = query.value
      const dictParams = { parent_code: this.currentData.dict_code }
      if (value) { dictParams['label'] = value }
      getDictDetail(dictParams).then(res => {
        if (res.code === 200) {
          this.dictTree = res.data.list
        }
        this.dictLoading = false
      }).catch(err => {
        this.dictLoading = false
        console.log(err)
      })
    },
    getDictList() {
      this.dictLoading = true
      const query = this.query
      const value = query.value
      const dictParams = { parent_code: this.currentData.dict_code }
      if (value) { dictParams['label'] = value }
      getDictList(dictParams).then(res => {
        if (res.code === 200) {
          this.dictTree = res.data.list
        }
        this.dictLoading = false
      }).catch(err => {
        this.dictLoading = false
        console.log(err)
      })
    },
    subDelete(id) {
      this.delLoading = true
      del(id).then(res => {
        this.delLoading = false
        this.$refs[id].doClose()
        this.getDictDetail()
        this.$message({
          showClose: true,
          type: 'success',
          message: '删除成功!',
          duration: 2500
        })
      }).catch(err => {
        this.delLoading = false
        this.$refs[id].doClose()
        console.log(err)
      })
    },
    selectAll(selection) {
      this.checkedKeys = !this.checkedKeys
      this.splite(this.data, this.checkedKeys)
    },
    /**
     * 递归处理数据
     */
    splite(data, flag) {
      data.forEach((row) => {
        this.$refs.treeTable.toggleRowSelection(row, flag)
        if (row.children !== undefined) {
          this.splite(row.children)
        }
      })
    },
    // 多选
    handleSelectionChange(val) {
      this.multipleSelection = val
    },
    // 批量删除
    handleMultiDel() {
      this.delLoading = true
      const idsLen = this.multipleSelection.length
      if (idsLen > 0) {
        let ids = ''
        for (var index = 0; index < idsLen; index++) {
          if (index + 1 === idsLen) {
            ids += this.multipleSelection[index].id
          } else {
            ids += this.multipleSelection[index].id + ','
          }
        }
        multiDelete(ids).then(res => {
          if (res.code === 200) {
            this.page = 1
            this.init()
            this.$message({
              showClose: true,
              type: 'success',
              message: '删除成功!',
              duration: 2500
            })
          }
          this.delLoading = false
        }).catch(err => {
          this.delLoading = false
          console.log(err)
        })
      } else {
        this.delLoading = false
        this.$message({
          showClose: true,
          type: 'warning',
          message: '请选择所需删除行!',
          duration: 2500
        })
        // Notification.error({
        //   title: '错误',
        //   message: '请选择所需删除行'
        // })
      }
    },
    // 触发页面显示配置的筛选
    filterNode(value, data, node) {
      // 如果什么都没填就直接返回
      if (!value) return true
      // 如果传入的value和data中的label相同说明是匹配到了
      if (data.label.indexOf(value) !== -1) {
        return true
      }
      // 否则要去判断它是不是选中节点的子节点
      return this.checkBelongToChooseNode(value, data, node)
    },
    // 判断传入的节点是不是选中节点的子节点
    checkBelongToChooseNode(value, data, node) {
      const level = node.level
      // 如果传入的节点本身就是一级节点就不用校验了
      if (level === 1) {
        return false
      }
      // 先取当前节点的父节点
      let parentData = node.parent
      // 遍历当前节点的父节点
      let index = 0
      while (index < level - 1) {
        // 如果匹配到直接返回
        if (parentData.data.label.indexOf(value) !== -1) {
          return true
        }
        // 否则的话再往上一层做匹配
        parentData = parentData.parent
        index++
      }
      // 没匹配到返回false
      return false
    }
  }
}
</script>

<style scoped>
/deep/.el-table th>.cell {
    display: inline-block;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    position: relative;
    vertical-align: middle;
    padding-left: 10px;
    padding-right: 10px;
    width: 100%;
    text-align: center;
}

/deep/.el-input__inner {
    -webkit-appearance: none;
    background-color: #FFF;
    background-image: none;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    color: #606266;
    font-size: inherit;
    height: 30.5px;
    line-height: 30.5px;
    outline: 0;
    padding: 0 15px;
    -webkit-transition: border-color .2s cubic-bezier(.645,.045,.355,1);
    transition: border-color .2s cubic-bezier(.645,.045,.355,1);
    width: 100%;
}

.tree_menu{
  position: fixed;
  display: block;
  z-index: 20000;
  background-color: #fff;
  padding:5px 0;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  box-shadow:0 2px 12px 0 rgba(0,0,0,.1);
}

.tree_menu ul {
    margin: 0;
    padding: 0;
  }
.tree_menu ul li{
  list-style: none;
  margin:0;
  padding:0 15px;
  font-size: 14px;
  line-height: 30px;
  cursor: pointer;
}
.tree_menu ul li:hover{
  background-color: #ebeef5
}
</style>
